package com.wontube.smr.bo.sites;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wontube.client.extension.utils.StringUtils;
import com.wontube.client.modle.vo.PagenateInfo;
import com.wontube.client.modle.vo.PagenateSupport;
import com.wontube.core.dao.mybatis.QueryExample;
import com.wontube.smr.bo.constants.SiteConstants;
import com.wontube.smr.bo.sites.youtube.feed.YouTubeFeedsBO;
import com.wontube.smr.client.model.po.MVChart;
import com.wontube.smr.client.model.po.Movie;
import com.wontube.smr.client.model.vo.MVChartItems;
import com.wontube.smr.client.model.vo.MovieItems;
import com.wontube.smr.dao.bo.MVSelectDao;
import com.wontube.smr.dao.bo.MovieSelectDao;
import com.wontube.smr.dao.bo.MovieTodayDao;
import com.wontube.smr.dao.bo.MovieWeekDao;
import com.wontube.smr.dao.mapper.MovieMapper;
import com.wontube.smr.pub.DefaultDBHelper;
import com.wontube.smr.web.client.model.bo.QueryItemParams;

/**
 * @author yuechao
 *
 */
public final class MVSelectBO {
	private final static Logger logger = LoggerFactory.getLogger(MVSelectBO.class);
	
	private MVSelectBO() {
	}
	
	public static final MovieItems listRelated(final String movieId, final PagenateInfo pageInfo){		
		if (movieId.startsWith("yt")) {
			String videoId = movieId.substring("yt".length());
			try {
				return YouTubeFeedsBO.listRelated(videoId, pageInfo);
			} catch (Exception e) {
				return new MovieItems();
			}
		}
		
		return MovieSelectDao.selectRelatedMusics(movieId, pageInfo);
	}
	
	/**
	 * 由于暂时拿不到 youtube 的数据，只从数据库取
	 * 
	 * @param updatePeriod
	 * @param genreName
	 * @param dbFactor
	 * @param pageInfo
	 * @return
	 */
	public static MovieItems selectMusics(String updatePeriod, String genreName, double dbFactor, PagenateInfo pageInfo) {
		if (pageInfo.getPageSize() > PagenateSupport.maxPageSize) {
			pageInfo.setPageSize(PagenateSupport.maxPageSize);
		}
		
		MovieItems items = new MovieItems(pageInfo);
		if (dbFactor > 1 || dbFactor < 0) {
			dbFactor = 1;
		}

		if (MVChart.UPDATE_PERIOD_ALL_TIME.equals(updatePeriod)) {
			items = MovieSelectDao.selectMusics(genreName, pageInfo);
		} else if (MVChart.UPDATE_PERIOD_DAILY.equals(updatePeriod)) {
			items = MovieTodayDao.selectMusics(genreName, pageInfo);
		} else if (MVChart.UPDATE_PERIOD_WEEKLY.equals(updatePeriod)) {
			items = MovieWeekDao.selectMusics(genreName, pageInfo);
		} else if (MVChart.UPDATE_PERIOD_RECENT.equals(updatePeriod)) {
			items = MovieSelectDao.selectRecentMusics(genreName, pageInfo);
		}

		return items;
	}	
	
	public static MovieItems searchMusics(String query, double dbFactor, PagenateInfo pageInfo) {
		MovieItems items = new MovieItems(pageInfo);
				
		if (dbFactor > 1 || dbFactor < 0) {
			dbFactor = 1;
		}
		
		// 优先展示资源库的内容
		int dbPageSize = (int)(pageInfo.getPageSize() * dbFactor);
		int dbSize = 0;
		int dbTotal = 0;
		if(dbPageSize > 0){
			PagenateInfo dbPageInfo = new PagenateInfo(pageInfo.getPageNo(), dbPageSize);
			items = MovieSelectDao.search(query, Movie.TYPE_MUSIC, dbPageInfo);
			dbSize = items.getItems().size();
			dbTotal = items.getTotalCount();
		}
		
		//Youtube
		// 展示YouTube内容
		int ybPageSize = pageInfo.getPageSize() - dbSize;		
		int ybSize = 0;
		int ybTotal = 0;
		if (ybPageSize > 0) {
			PagenateInfo feedsPageInfo = new PagenateInfo(pageInfo.getPageNo(), ybPageSize);
					
			MovieItems feedsItems = null;
			try {
				feedsItems = YouTubeFeedsBO.searchVideoFeeds(query, Movie.TYPE_MUSIC, feedsPageInfo);
			} catch (Exception e) {
			}
			
			if(feedsItems != null){
				ybSize = feedsItems.getItems().size();
				ybTotal = feedsItems.getTotalCount();
			}
			
			if(ybSize < ybPageSize && dbSize == dbPageSize){
				//重新db
				dbPageSize += ybPageSize - ybSize;
				PagenateInfo dbPageInfo = new PagenateInfo(pageInfo.getPageNo(), dbPageSize);
				items = MovieSelectDao.search(query, Movie.TYPE_MUSIC, dbPageInfo);				
			}		
						
			if(feedsItems != null){
				for (Movie movie : feedsItems.getItems()) {
					items.getItems().add(movie);
				}
			}						
		}	
		
		items.setTotalCount(dbTotal + ybTotal);
		
		return items;
	}
	
	public static MovieItems selectVevoMusics(PagenateInfo pageInfo){		
		return selectVevoMusics(new QueryItemParams(), pageInfo);
	}
		
	public static MovieItems selectVevoMusics(QueryItemParams params, PagenateInfo pageInfo){		
		String period = params.getPeriod();
		if(StringUtils.isNullOrEmpty(period)){
			return MovieSelectDao.selectVevoMusics(params, pageInfo);
		}else{
			if(period.equals(MVChart.UPDATE_PERIOD_ALL_TIME)){
				return MovieSelectDao.selectVevoMusics(params, pageInfo);
			}else if(period.equals(MVChart.UPDATE_PERIOD_DAILY)){
				return MovieTodayDao.selectMusics(params, pageInfo);
			}else if(period.equals(MVChart.UPDATE_PERIOD_WEEKLY)){
				return MovieWeekDao.selectMusics(params, pageInfo);
			}else if(period.equals(MVChart.UPDATE_PERIOD_RECENT)){
				return MovieSelectDao.selectRecentMusic(params, pageInfo);
			}
		}
		
		return  new MovieItems(pageInfo);
	}	
	
	public static MVChartItems listVevoTopArtists(PagenateInfo pageInfo) {
		return selectVevoArtistCharts(null, pageInfo);
	}
	
	public static MVChartItems selectVevoArtistCharts(String period, PagenateInfo pageInfo){
		if(StringUtils.isNullOrEmpty(period)){
			period = MVChart.UPDATE_PERIOD_DAILY;
		}
		
		MVChartItems items =MVSelectDao.selectMVCharts(MVChart.CATEGORY_VEVO_TOP_ARTISTS, 
				period, pageInfo);
		
		SqlSession session = DefaultDBHelper.getSqlSession(false);
		try {
			MovieMapper movieMapper = session.getMapper(MovieMapper.class);
			QueryExample ex = new QueryExample();			
			
			List<MVChart> charts = new ArrayList<MVChart>();
			//重新计算video count
			for (MVChart chart : items.getItems()) {
				ex.clear();
				ex.or().addCriterion("movie.website=", SiteConstants.WEBSITE_VEVO)
					.addCriterion("movie.movie_type=", Movie.TYPE_MUSIC)
					.addCriterion("movie.actors=", chart.getSinger());
				int count = movieMapper.countByExample(ex);
				if(count > 0){
					chart.setVideoCount(count);
					charts.add(chart);
				}				
			}
			
			items.setItems(charts);
			session.commit();
		} finally {
			session.close();
		}
		
		return items;
	}
	
	public static Movie getYoutubeMV(String mvId) {
		//get from db
		Movie movie = MovieSelectDao.getMovie(mvId);
		if(movie == null){
			if(mvId.startsWith(SiteConstants.ID_PREFIX_YOUTUBE)){
				mvId = mvId.substring(SiteConstants.ID_PREFIX_YOUTUBE.length());
			}
			movie = YouTubeFeedsBO.getSingle(mvId);
			if(movie != null){	
				String desc = movie.getDescription();
				if(desc.length() >= 2000){
					movie.setDescription(desc.substring(0, 2000));
				}
				//save to db
				SqlSession session = DefaultDBHelper.getSqlSession(true);
				try {					
					MovieMapper movieMapper = session.getMapper(MovieMapper.class);
					movieMapper.insert(movie);
				} catch(Exception e){
					logger.error("error happen when inserting Youtube music", e);
				} finally {
					session.close();
				}
			}			
		}
		
		return movie;
	}
}
